home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-12-07 | 53.0 KB | 2,111 lines |
- Newsgroups: comp.sources.misc
- From: wietse@wzv.win.tue.nl (Wietse Venema)
- Subject: v26i094: unproto - compile ANSI C with old C compiler, Part01/02
- Message-ID: <csm-v26i094=unproto.083344@sparky.IMD.Sterling.COM>
- X-Md4-Signature: 69685c0673793ce6c539657a3d1de2ab
- Date: Sun, 1 Dec 1991 14:35:08 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: wietse@wzv.win.tue.nl (Wietse Venema)
- Posting-number: Volume 26, Issue 94
- Archive-name: unproto/part01
- Environment: SYSV2, SunOS
- Supersedes: unproto: Volume 23, Issue 12-13
-
- This is a filter that sits in between the C preprocessor and the next C
- compiler stage, and that on the fly rewrites ANSI C to old C. Its
- primary application is to compile ANSI C software in UNIX environments
- that do not (yet) have an ANSI C compiler and that cannot run GCC
- because of technical or political problems.
-
- Problems solved with this release:
-
- Minor: the program was originally intended for the compilation of
- already tested ANSI C source, so that diagnostics from the native C
- compiler would be sufficient. The present release produces better
- diagnostics, so that it can also be used for program development.
-
- Major: the template Makefile suggested that all #pragma directives be
- filtered out. This turns out to be a bad idea because some non-ANSI
- compilers (SunOS) rely on #pragmas to correctly handle the unusual flow
- control caused by vfork(2), setjmp(3) etcetera. A warning to this
- effect has been added to the Makefile.
-
- No changes were made to the actual filter logic; output should be
- identical to that of the previous release.
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 2)."
- # Contents: Makefile README cpp.sh error.c error.h example.c
- # example.out stdarg.h symbol.c symbol.h tok_class.c tok_io.c
- # tok_pool.c token.h unproto.1 varargs.c vstring.c vstring.h
- # Wrapped by wietse@wzv on Sun Dec 1 12:43:04 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f Makefile -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"Makefile\"
- else
- echo shar: Extracting \"Makefile\" \(2877 characters\)
- sed "s/^X//" >Makefile <<'END_OF_Makefile'
- X# @(#) Makefile 1.3 91/12/01 12:37:57
- X
- X## BEGIN CONFIGURATION STUFF
- X
- X# For maximal flexibility, the "/lib/cpp | unproto" pipeline can be
- X# packaged as an executable shell script (see the provided "cpp.sh" script)
- X# that should be installed as "/whatever/cpp". This script should then be
- X# specified to the C compiler as a non-default preprocessor.
- X#
- X# PROG = unproto
- X# PIPE =
- X
- X# For maximal performance, the overhead of shell script inpretation can
- X# be eliminated by having the unprototyper program itself open the pipe
- X# to the preprocessor. In that case, define the PIPE_THROUGH_CPP macro
- X# as the path name of the default C preprocessor (usually "/lib/cpp"),
- X# install the unprototyper as "/whatever/cpp" and specify that to the C
- X# compiler as a non-default preprocessor.
- X#
- XPROG = cpp
- XPIPE = -DPIPE_THROUGH_CPP=\"/lib/cpp\"
- X
- X# Some compilers complain about some #directives. The following is only a
- X# partial solution, because the directives are still seen by /lib/cpp.
- X# Be careful with filtering out #pragma, because some non-ANSI compilers
- X# (SunOS) rely on its use.
- X#
- X# SKIP = -DIGNORE_DIRECTIVES=\"pragma\",\"foo\",\"bar\"
- X#
- XSKIP =
- X
- X# If you need support for functions that implement ANSI-style variable
- X# length argument lists, edit the stdarg.h file provided with this
- X# package so that it contains the proper definitions for your machine.
- X
- X## END CONFIGURATION STUFF
- X
- XSHELL = /bin/sh
- X
- XCFILES = tok_io.c tok_class.c tok_pool.c unproto.c vstring.c symbol.c error.c
- XHFILES = error.h token.h vstring.h symbol.h
- XSCRIPTS = cpp.sh
- XSAMPLES = stdarg.h varargs.c example.c example.out
- XSOURCES = README Makefile $(CFILES) $(HFILES) $(SCRIPTS) $(SAMPLES)
- XFILES = $(SOURCES) unproto.1
- XOBJECTS = tok_io.o tok_class.o tok_pool.o unproto.o vstring.o symbol.o error.o
- X
- XCFLAGS = -O $(PIPE) $(SKIP)
- X#CFLAGS = -O -pg -Dstatic= $(PIPE) $(SKIP)
- X#CFLAGS = -g $(PIPE) $(SKIP) -DDEBUG
- X
- X$(PROG): $(OBJECTS)
- X cc $(CFLAGS) -o $@ $(OBJECTS) $(MALLOC)
- X
- X# For linting, enable all bells and whistles.
- X
- Xlint:
- X lint -DPIPE_THROUGH_CPP=\"foo\" -DIGNORE_DIRECTIVES=\"foo\",\"bar\" \
- X $(CFILES)
- X
- X# Testing requires that the program is compiled with -DDEBUG
- X
- Xtest: $(PROG) example.c example.out
- X ./cpp example.c >example.tmp
- X @echo the following diff command should produce no output
- X diff -b example.out example.tmp
- X rm -f example.tmp
- X
- Xshar: $(FILES)
- X @shar $(FILES)
- X
- Xarchive:
- X $(ARCHIVE) $(SOURCES)
- X
- Xclean:
- X rm -f *.o core cpp unproto mon.out varargs.o varargs example.tmp
- X
- Xerror.o : error.c token.h error.h Makefile
- Xsymbol.o : symbol.c token.h symbol.h Makefile
- Xtok_class.o : tok_class.c error.h vstring.h token.h symbol.h Makefile
- Xtok_io.o : tok_io.c token.h vstring.h error.h Makefile
- Xtok_pool.o : tok_pool.c token.h vstring.h Makefile
- Xunproto.o : unproto.c vstring.h stdarg.h token.h error.h symbol.h Makefile
- Xvarargs.o : varargs.c stdarg.h Makefile
- Xvstring.o : vstring.c vstring.h Makefile
- END_OF_Makefile
- if test 2877 -ne `wc -c <Makefile`; then
- echo shar: \"Makefile\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f README -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"README\"
- else
- echo shar: Extracting \"README\" \(5616 characters\)
- sed "s/^X//" >README <<'END_OF_README'
- X@(#) README 1.3 91/12/01 12:37:55
- X
- Xunproto - ANSI C to old C converter
- X
- XPurpose:
- X
- XThis is a filter that sits in between the C preprocessor and the next C
- Xcompiler stage, and that on the fly rewrites ANSI C to old C. Its
- Xprimary application is to compile ANSI C software in UNIX environments
- Xthat do not (yet) have an ANSI C compiler and that cannot run GCC
- Xbecause of technical or political problems.
- X
- XThe filter leaves old-style C alone, and de-ANSI-fies function
- Xheadings, function pointer type declarations (and casts), function type
- Xdeclarations, and combinations thereof. Many freely-distributable
- Xunprotoizers have problems with the latter because they are based on a
- Xnon-recursive algorithm or even make assumptions about code layout.
- X
- XThe unprototyper has support for systems that require special tricks
- Xfor variadic functions (fortunately, many don't). A sample `stdarg.h'
- Xfile is provided with support for sparc, mc68k, 80x86, vax and others.
- X
- XThe program has been tested on a Sun SLC running SunOS 4.1.1 and on a
- X80286 PC clone running Microport's version of System V Release 2. It
- Xruns at about the same speed as /lib/cpp, so it should have negigible
- Ximpact on compilation times.
- X
- XProblems solved with this release:
- X
- XMinor: the program was originally intended for the compilation of
- Xalready tested ANSI C source, so that diagnostics from the native C
- Xcompiler would be sufficient. The present release produces better
- Xdiagnostics, so that it can also be used for program development.
- X
- XMajor: the template Makefile suggested that all #pragma directives be
- Xfiltered out. This turns out to be a bad idea because some non-ANSI
- Xcompilers (SunOS) rely on #pragmas to correctly handle the unusual flow
- Xcontrol caused by vfork(2), setjmp(3) etcetera. A warning to this
- Xeffect has been added to the Makefile.
- X
- XNo changes were made to the actual filter logic; output should be
- Xidentical to that of the previous release.
- X
- XRestrictions:
- X
- XOther ANSI-isms are just passed on without modification, such as
- Xtrigraphs, token pasting (##), #pragmas, stringizing (#text) and
- Xstring concatenation ("string1" "string2").
- X
- XThe unprototyper does not understand declarations of (object). The
- Xresult (the object disappears) will be a syntax error so this should
- Xnot go by unnoticed.
- X
- XSome C programmers rely on ANSI-style prototypes for the automatic type
- Xconversion of function arguments. The unprototyper, however, does not
- Xgenerate casts. The lack of automatic conversion between integral
- Xand/or pointer argument types should not be a problem in environments
- Xwhere sizeof(int) == sizeof(long) == sizeof(pointer). A more serious
- Xproblem is the lack of automatic type conversions beteen integral and
- Xfloating-point function argument types. Let lint(1) be your friend.
- X
- XOperation:
- X
- XThis package implements an non-default C preprocessor (the output from
- Xthe default C preprocessor being piped through the unprototyper). How
- Xone tells the C compiler to use an non-default preprocessor program is
- Xsomewhat compiler-dependent:
- X
- X SunOS 4.x: cc -Qpath directory_with_non-default_cpp ...
- X
- X SysV Rel2: cc -Bdirectory_with_non-default_cpp/ -tp ...
- X
- XYour C compiler manual should provide the necessary information.
- X
- XOn some systems the lint(1) command is just a shell script, and writing
- Xa version that uses the unprototyper should not be too hard. With SunOS
- X4.x, /usr/bin/lint is not a shell script, but it does accept the same
- Xsyntax as the cc(1) command for the specification of a non-default
- Xcompiler pass.
- X
- XYou may have to do some research on the lint command provided with your
- Xown machine.
- X
- XConfiguration:
- X
- XCheck the contents of the `stdarg.h' file provided with this package.
- XThis file serves a dual purpose. It should be included by C source file
- Xthat implements ANSI-style variadic functions. It is also used to
- Xconfigure the `unproto' program so that it emits the proper magic for
- Xthe `...' construct.
- X
- XThe `stdarg.h' file contains definitions for the sparc architecture and
- Xfor architectures that pass arguments via the stack (usually OK for
- X80*86, mc68k and vax C compilers). Risc processors often need special
- Xtricks. These are usually found in the file `/usr/include/varargs.h'.
- X
- XThe file `varargs.c' provided with this package can be used to verify
- Xthat the `stdarg.h' file has been set up correctly.
- X
- XFor maximal flexibility, you can use the `cpp' shell script provided
- Xwith this package to set up the pipe between the default C preprocessor
- Xand the unprototyper command. The script assumes that the unprototyper
- Xbinary is called `unproto'. See the cpp.sh script and the Makefile for
- Xdetails.
- X
- XThe overhead of shell-script interpretation can be avoided by having
- Xthe unprototyper itself open the pipe to the C preprocessor. In this
- Xcase, the `unproto.c' source file should be compiled with the
- X`PIPE_THROUGH_CPP' macro defined as the pathname of the C preprocessor
- X(usually `/lib/cpp'), and the unprototyper binary should be called
- X`cpp'. See the Makefile for details.
- X
- XInstallation:
- X
- XInstall the `stdarg.h' include file and the `unproto.1' manual page in
- Xsuitable places.
- X
- XIf you use the `cpp' shell script to pipe the preprocessor output
- Xthrough the unprototyper program, install the `unproto' binary in a
- Xplace where the `cpp' shell script can find it, and install the `cpp'
- Xshell script in a suitable place.
- X
- XIf the unprototyper itself opens the pipe to the C preprocessor (i.e.
- Xthe unprototyper was built with the `PIPE_THROUGH_CPP' macro defined),
- Xinstall the `cpp' unprototyper binary in a suitable place.
- X
- X Wietse Venema
- X wietse@wzv.win.tue.nl
- X Eindhoven University of Technology
- X The Netherlands
- END_OF_README
- if test 5616 -ne `wc -c <README`; then
- echo shar: \"README\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f cpp.sh -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"cpp.sh\"
- else
- echo shar: Extracting \"cpp.sh\" \(311 characters\)
- sed "s/^X//" >cpp.sh <<'END_OF_cpp.sh'
- X#!/bin/sh
- X
- X# @(#) cpp.sh 1.2 91/09/22 21:21:43
- X
- X# Unprototypeing preprocessor for non-ANSI C compilers. Define __STDC__
- X# if you have enough courage. You will have to modify this script if
- X# your cc(1) command specifies output file names to the preprocessor.
- X
- Xexec /lib/cpp "$@" -Dconst= -Dvolatile= | unproto
- END_OF_cpp.sh
- if test 311 -ne `wc -c <cpp.sh`; then
- echo shar: \"cpp.sh\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f error.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"error.c\"
- else
- echo shar: Extracting \"error.c\" \(1675 characters\)
- sed "s/^X//" >error.c <<'END_OF_error.c'
- X/*++
- X/* NAME
- X/* error 3
- X/* SUMMARY
- X/* diagnostics
- X/* PACKAGE
- X/* unproto
- X/* SYNOPSIS
- X/* #include "error.h"
- X/*
- X/* void error(quit, text)
- X/* int quit;
- X/* char *text;
- X/*
- X/* void error_where(quit, path, line, text)
- X/* int quit;
- X/* char *path;
- X/* int line;
- X/* char *text;
- X/* DESCRIPTION
- X/* The routines in this file print a diagnostic (text) and optionally
- X/* terminate the program (quit != 0) with exit status "quit".
- X/*
- X/* error() provides a default context, i.e. the source-file
- X/* coordinate of the last read token.
- X/*
- X/* error_where() allows the caller to explicitly specify context: path
- X/* is a source-file name, and line is a line number.
- X/*
- X/* context is ignored if the line number is zero or if the path
- X/* is an empty string.
- X/* AUTHOR(S)
- X/* Wietse Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* LAST MODIFICATION
- X/* 91/11/30 21:10:35
- X/* VERSION/RELEASE
- X/* 1.1
- X/*--*/
- X
- Xstatic char error_sccsid[] = "@(#) error.c 1.1 91/11/30 21:10:35";
- X
- X/* C library */
- X
- X#include <stdio.h>
- X
- Xvoid exit();
- X
- X/* Application-specific stuff */
- X
- X#include "token.h"
- X#include "error.h"
- X
- X/* error - report problem (implicit context) and optionally quit */
- X
- Xvoid error(quit, text)
- Xint quit;
- Xchar *text;
- X{
- X error_where(quit, curr_path, curr_line, text);
- X}
- X
- X/* error_where - report problem (explicit context) and optionally quit */
- X
- Xvoid error_where(quit, path, line, text)
- Xint quit;
- Xchar *path;
- Xint line;
- Xchar *text;
- X{
- X if (line && path[0])
- X fprintf(stderr, "%s, line %d: ", path, line);
- X fprintf(stderr, "%s\n", text);
- X if (quit)
- X exit(quit);
- X}
- END_OF_error.c
- if test 1675 -ne `wc -c <error.c`; then
- echo shar: \"error.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f error.h -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"error.h\"
- else
- echo shar: Extracting \"error.h\" \(144 characters\)
- sed "s/^X//" >error.h <<'END_OF_error.h'
- X/* @(#) error.h 1.1 91/11/30 21:10:36 */
- X
- Xextern void error(); /* default context */
- Xextern void error_where(); /* user-specified context */
- END_OF_error.h
- if test 144 -ne `wc -c <error.h`; then
- echo shar: \"error.h\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f example.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"example.c\"
- else
- echo shar: Extracting \"example.c\" \(2062 characters\)
- sed "s/^X//" >example.c <<'END_OF_example.c'
- X /*
- X * @(#) example.c 1.2 91/09/22 21:21:45
- X *
- X * Examples of things that can be done with the unproto package
- X */
- X
- X /*
- X * New-style argument list with structured argument, one field being pointer
- X * to function returning pointer to function with function-pointer argument
- X */
- X
- Xx(struct {
- X struct {
- X int (*(*foo) (int (*arg1) (double))) (float arg2);
- X } foo;
- X} baz) {
- X return (0);
- X}
- X
- X /*
- X * Old-style argument list with new-style argument type, declaration
- X * embedded within block. Plus a couple assignments with function calls that
- X * look like casts.
- X */
- X
- Xfoo(bar)
- Xint (*(*bar) (float)) (int);
- X{
- X int (*baz) (int) = (int (*) (int)) 0,
- X y = (y * (*baz) (y)),
- X *(*z) (int) = (int *(*) (int)) 0;
- X
- X struct { int (*foo)(int); } *(*s)(int) =
- X (struct { int (*foo)(int); } *(*)(int)) 0;
- X
- X {
- X y = (y * (*baz) (y));
- X }
- X {
- X z = (int *(*) (int)) 0;
- X }
- X {
- X s = (struct { int (*foo)(int); } *(*)(int)) 0;
- X }
- X
- X return (0);
- X}
- X
- X/* Multiple declarations in one statement */
- X
- Xtest1()
- X{
- X int foo2,*(*(*bar)(int))(float),*baz(double);
- X}
- X
- X/* Discriminate declarations from executable statements */
- X
- Xtest2(char *y)
- X{
- X int foo = 5,atoi(char *);
- X
- X foo = 5,atoi(y);
- X}
- X
- X/* Declarations without explicit type */
- X
- Xtest3,test4(int);
- X
- Xtest5(int y)
- X{
- X {
- X test3;
- X }
- X {
- X test4(y);
- X }
- X}
- X
- Xtest6[1],test7(int);
- X
- Xtest7(int x)
- X{
- X {
- X test6[1];
- X }
- X {
- X test7(x);
- X }
- X}
- X
- X/* Checking a complicated cast */
- X
- Xstruct {
- X struct {
- X int (*f)(int), o;
- X } bar;
- X} (*baz2)(int) = (struct { struct { int (*f)(int), o; } bar; } (*)(int)) 0;
- X
- X/* Distinguish things with the same shape but with different meaning */
- X
- Xtest8(x)
- X{
- X {
- X struct {
- X int foo;
- X } bar(int);
- X }
- X {
- X do {
- X int foo;
- X } while (x);
- X }
- X}
- X
- X/* Do not think foo(*bar) is a function pointer declaration */
- X
- Xtest9(char *bar)
- X{
- X foo(*bar);
- X}
- X
- X/* another couple of special-cased words. */
- X
- Xtest10(int x)
- X{
- X {
- X int test10(int);
- X do test10(x);
- X while (x);
- X }
- X {
- X return test10(x);
- X }
- X}
- X
- Xtest11(int *x)
- X{
- X while (*x)
- X (putchar(*x++));
- X}
- END_OF_example.c
- if test 2062 -ne `wc -c <example.c`; then
- echo shar: \"example.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f example.out -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"example.out\"
- else
- echo shar: Extracting \"example.out\" \(1994 characters\)
- sed "s/^X//" >example.out <<'END_OF_example.out'
- X# 1 "example.c"
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- Xx
- X
- X
- X
- X(baz)
- X# 16 "example.c"
- Xstruct { struct { int (*(*foo)())(); } foo;} baz;
- X# 16 "example.c"
- X{/*1*/
- X /* end dcls */return (0);
- X}/*1*/
- X
- X
- X
- X
- X
- X
- X
- Xfoo
- X(bar)int (*(*bar)())();
- X{/*1*/
- X int (*baz)() = (int (*)()) 0,
- X y = (y * (*baz)(y)),
- X *(*z)() = (int *(*)()) 0;
- X
- X struct {/*2*/ int (*foo)(); }/*2*/ *(*s)() =
- X (struct { int (*foo)(); } *(*)()) 0;
- X
- X /* end dcls */{/*2*/
- X y /* end dcls */= (y * (*baz)(y));
- X }/*2*/
- X {/*2*/
- X z /* end dcls */= (int *(*)()) 0;
- X }/*2*/
- X {/*2*/
- X s /* end dcls */= (struct { int (*foo)(); } *(*)()) 0;
- X }/*2*/
- X
- X return (0);
- X}/*1*/
- X
- X
- X
- Xtest1
- X()
- X# 52 "example.c"
- X{/*1*/
- X int foo2,*(*(*bar)())(),*baz();
- X}/*1*/
- X
- X
- X
- Xtest2
- X(y)
- X# 59 "example.c"
- Xchar *y;
- X# 59 "example.c"
- X{/*1*/
- X int foo = 5,atoi();
- X
- X foo /* end dcls */= 5,atoi(y);
- X}/*1*/
- X
- X
- X
- Xtest3,test4();
- X
- Xtest5
- X(y)
- X# 70 "example.c"
- Xint y;
- X# 70 "example.c"
- X{/*1*/
- X /* end dcls */{/*2*/
- X test3/* end dcls */;
- X }/*2*/
- X {/*2*/
- X test4/* end dcls */(y);
- X }/*2*/
- X}/*1*/
- X
- Xtest6[1],test7();
- X
- Xtest7
- X(x)
- X# 82 "example.c"
- Xint x;
- X# 82 "example.c"
- X{/*1*/
- X /* end dcls */{/*2*/
- X test6/* end dcls */[1];
- X }/*2*/
- X {/*2*/
- X test7/* end dcls */(x);
- X }/*2*/
- X}/*1*/
- X
- X
- X
- Xstruct {/*1*/
- X struct {/*2*/
- X int (*f)(), o;
- X }/*2*/ bar;
- X}/*1*/ (*baz2)() = (struct { struct { int (*f)(), o; } bar; } (*)()) 0;
- X
- X
- X
- Xtest8
- X(x)
- X# 102 "example.c"
- X{/*1*/
- X /* end dcls */{/*2*/
- X struct {/*3*/
- X int foo;
- X }/*3*/ bar();
- X }/*2*/
- X {/*2*/
- X /* end dcls */do {/*3*/
- X int foo;
- X }/*3*/ while (x);
- X }/*2*/
- X}/*1*/
- X
- X
- X
- Xtest9
- X(bar)
- X# 118 "example.c"
- Xchar *bar;
- X# 118 "example.c"
- X{/*1*/
- X foo/* end dcls */(*bar);
- X}/*1*/
- X
- X
- X
- Xtest10
- X(x)
- X# 125 "example.c"
- Xint x;
- X# 125 "example.c"
- X{/*1*/
- X /* end dcls */{/*2*/
- X int test10();
- X /* end dcls */do test10(x);
- X while (x);
- X }/*2*/
- X {/*2*/
- X /* end dcls */return test10(x);
- X }/*2*/
- X}/*1*/
- X
- Xtest11
- X(x)
- X# 137 "example.c"
- Xint *x;
- X# 137 "example.c"
- X{/*1*/
- X /* end dcls */while (*x)
- X (putchar(*x++));
- X}/*1*/
- END_OF_example.out
- if test 1994 -ne `wc -c <example.out`; then
- echo shar: \"example.out\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f stdarg.h -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"stdarg.h\"
- else
- echo shar: Extracting \"stdarg.h\" \(1413 characters\)
- sed "s/^X//" >stdarg.h <<'END_OF_stdarg.h'
- X /*
- X * @(#) stdarg.h 1.2 91/11/30 21:10:39
- X *
- X * Sample stdarg.h file for use with the unproto filter.
- X *
- X * This file serves two purposes.
- X *
- X * 1 - As an include file for use with ANSI-style C source that implements
- X * variadic functions.
- X *
- X * 2 - To configure the unproto filter itself. If the _VA_ALIST_ macro is
- X * defined, its value will appear in the place of the "..." in argument
- X * lists of variadic function *definitions* (not declarations).
- X *
- X * Compilers that pass arguments via the stack can use the default code at the
- X * end of this file (this usually applies for the VAX, MC68k and 80*86
- X * architectures).
- X *
- X * RISC-based systems often need special tricks. An example of the latter is
- X * given for the SPARC architecture. Read your /usr/include/varargs.h for
- X * more information.
- X *
- X * You can use the varargs.c program provided with the unproto package to
- X * verify that the stdarg.h file has been set up correctly.
- X */
- X
- X#ifdef sparc
- X# define _VA_ALIST_ "__builtin_va_alist"
- X typedef char *va_list;
- X# define va_start(ap, p) (ap = (char *) &__builtin_va_alist)
- X# define va_arg(ap, type) ((type *) __builtin_va_arg_incr((type *) ap))[0]
- X# define va_end(ap)
- X#else /* vax, mc68k, 80*86 */
- X typedef char *va_list;
- X# define va_start(ap, p) (ap = (char *) (&(p)+1))
- X# define va_arg(ap, type) ((type *) (ap += sizeof(type)))[-1]
- X# define va_end(ap)
- X#endif
- END_OF_stdarg.h
- if test 1413 -ne `wc -c <stdarg.h`; then
- echo shar: \"stdarg.h\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f symbol.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"symbol.c\"
- else
- echo shar: Extracting \"symbol.c\" \(3522 characters\)
- sed "s/^X//" >symbol.c <<'END_OF_symbol.c'
- X/*++
- X/* NAME
- X/* symbol 3
- X/* SUMMARY
- X/* rudimentary symbol table package
- X/* SYNOPSIS
- X/* #include "symbol.h"
- X/*
- X/* void sym_init()
- X/*
- X/* void sym_enter(name, type)
- X/* char *name;
- X/* int type;
- X/*
- X/* struct symbol *sym_find(name)
- X/* char *name;
- X/* DESCRIPTION
- X/* This is a rudimentary symbol-table package, just enough to
- X/* keep track of a couple of C keywords.
- X/*
- X/* sym_init() primes the table with C keywords. At present, most of
- X/* the keywords that have to do with types are left out.
- X/* We need a different strategy to detect type definitions because
- X/* we do not keep track of typedef names.
- X/*
- X/* sym_enter() adds an entry to the symbol table.
- X/*
- X/* sym_find() locates a symbol table entry (it returns 0 if
- X/* it is not found).
- X/* AUTHOR(S)
- X/* Wietse Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* LAST MODIFICATION
- X/* 91/11/30 21:10:33
- X/* VERSION/RELEASE
- X/* 1.2
- X/*--*/
- X
- Xstatic char symbol_sccsid[] = "@(#) symbol.c 1.2 91/11/30 21:10:33";
- X
- X/* C library */
- X
- Xextern char *strcpy();
- Xextern char *malloc();
- X
- X/* Application-specific stuff */
- X
- X#include "error.h"
- X#include "token.h"
- X#include "symbol.h"
- X
- X#define SYM_TABSIZE 20
- X
- Xstatic struct symbol *sym_tab[SYM_TABSIZE] = {0,};
- X
- X/* More string stuff. Maybe it should go to an #include file. */
- X
- X#define STREQ(x,y) (*(x) == *(y) && strcmp((x),(y)) == 0)
- X
- X/* hash - hash a string; original author: P. J. Weinberger at Bell Labs. */
- X
- Xstatic unsigned hash(s, size)
- Xregister char *s;
- Xunsigned size;
- X{
- X register unsigned long h = 0;
- X register unsigned long g;
- X
- X /*
- X * For a performance comparison with the hash function presented in K&R,
- X * first edition, see the "Dragon" book by Aho, Sethi and Ullman.
- X */
- X
- X while (*s) {
- X h = (h << 4) + *s++;
- X if (g = (h & 0xf0000000)) {
- X h ^= (g >> 24);
- X h ^= g;
- X }
- X }
- X return (h % size);
- X}
- X
- X/* sym_enter - enter symbol into table */
- X
- Xvoid sym_enter(name, type)
- Xchar *name;
- Xint type;
- X{
- X struct symbol *s;
- X int where;
- X
- X if ((s = (struct symbol *) malloc(sizeof(*s))) == 0
- X || (s->name = malloc(strlen(name) + 1)) == 0)
- X error(1, "out of memory");
- X (void) strcpy(s->name, name);
- X s->type = type;
- X
- X where = hash(name, SYM_TABSIZE);
- X s->next = sym_tab[where];
- X sym_tab[where] = s;
- X}
- X
- X/* sym_find - locate symbol definition */
- X
- Xstruct symbol *sym_find(name)
- Xregister char *name;
- X{
- X register struct symbol *s;
- X
- X /*
- X * This function is called for almost every "word" token, so it better be
- X * fast.
- X */
- X
- X for (s = sym_tab[hash(name, SYM_TABSIZE)]; s; s = s->next)
- X if (STREQ(name, s->name))
- X return (s);
- X return (0);
- X}
- X
- X /*
- X * Initialization data for symbol table. We do not enter keywords for types.
- X * We use a different strategy to detect type declarations because we do not
- X * keep track of typedef names.
- X */
- X
- Xstruct sym {
- X char *name;
- X int tokno;
- X};
- X
- Xstatic struct sym syms[] = {
- X "if", TOK_CONTROL,
- X "else", TOK_CONTROL,
- X "while", TOK_CONTROL,
- X "do", TOK_CONTROL,
- X "switch", TOK_CONTROL,
- X "case", TOK_CONTROL,
- X "default", TOK_CONTROL,
- X "return", TOK_CONTROL,
- X "continue", TOK_CONTROL,
- X "break", TOK_CONTROL,
- X "goto", TOK_CONTROL,
- X "struct", TOK_COMPOSITE,
- X "union", TOK_COMPOSITE,
- X 0,
- X};
- X
- X/* sym_init - enter known keywords into symbol table */
- X
- Xvoid sym_init()
- X{
- X register struct sym *p;
- X
- X for (p = syms; p->name; p++)
- X sym_enter(p->name, p->tokno);
- X}
- X
- END_OF_symbol.c
- if test 3522 -ne `wc -c <symbol.c`; then
- echo shar: \"symbol.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f symbol.h -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"symbol.h\"
- else
- echo shar: Extracting \"symbol.h\" \(318 characters\)
- sed "s/^X//" >symbol.h <<'END_OF_symbol.h'
- X/* @(#) symbol.h 1.1 91/09/22 21:21:42 */
- X
- Xstruct symbol {
- X char *name; /* symbol name */
- X int type; /* symbol type */
- X struct symbol *next;
- X};
- X
- Xextern void sym_enter(); /* add symbol to table */
- Xextern struct symbol *sym_find(); /* locate symbol */
- Xextern void sym_init(); /* prime the table */
- END_OF_symbol.h
- if test 318 -ne `wc -c <symbol.h`; then
- echo shar: \"symbol.h\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f tok_class.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"tok_class.c\"
- else
- echo shar: Extracting \"tok_class.c\" \(4091 characters\)
- sed "s/^X//" >tok_class.c <<'END_OF_tok_class.c'
- X/*++
- X/* NAME
- X/* tok_class 3
- X/* SUMMARY
- X/* token classification
- X/* PACKAGE
- X/* unproto
- X/* SYNOPSIS
- X/* #include "token.h"
- X/*
- X/* struct token *tok_class(skip)
- X/* int skip;
- X/* DESCRIPTION
- X/* tok_class() collects a single and composite tokens, and
- X/* recognizes keywords.
- X/* At present, the only composite tokens are ()-delimited,
- X/* comma-separated lists.
- X/*
- X/* The skip argument has the same meaning as with the tok_get()
- X/* function.
- X/* DIAGNOSTICS
- X/* The code complains if input terminates in the middle of a list.
- X/* BUGS
- X/* Does not preserve white space at the beginning of a list element
- X/* or after the end of a list.
- X/* AUTHOR(S)
- X/* Wietse Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* LAST MODIFICATION
- X/* 91/11/30 21:10:28
- X/* VERSION/RELEASE
- X/* 1.3
- X/*--*/
- X
- Xstatic char class_sccsid[] = "@(#) tok_class.c 1.3 91/11/30 21:10:28";
- X
- X/* C library */
- X
- X#include <stdio.h>
- X
- Xextern char *strcpy();
- X
- X/* Application-specific stuff */
- X
- X#include "error.h"
- X#include "vstring.h"
- X#include "token.h"
- X#include "symbol.h"
- X
- Xstatic struct token *tok_list();
- Xstatic void tok_list_struct();
- Xstatic void tok_list_append();
- X
- X/* tok_space_append - append trailing space except after list */
- X
- X#define tok_space_append(list,t) { \
- X if (list == 0 /* leading space*/ \
- X || list->tokno == TOK_LIST) \
- X tok_free(t); \
- X else \
- X tok_list_append(list, t); \
- X }
- X
- X/* tok_class - discriminate single tokens, keywords, and composite tokens */
- X
- Xstruct token *tok_class(skip)
- Xint skip;
- X{
- X register struct token *t;
- X register struct symbol *s;
- X
- X if (t = tok_get(skip)) {
- X switch (t->tokno) {
- X case '(': /* beginning of list */
- X t = tok_list(t);
- X break;
- X case TOK_WORD: /* look up keyword */
- X if (s = sym_find(t->vstr->str))
- X t->tokno = s->type;
- X break;
- X }
- X }
- X return (t);
- X}
- X
- X/* tok_list - collect ()-delimited, comma-separated list of tokens */
- X
- Xstatic struct token *tok_list(t)
- Xstruct token *t;
- X{
- X register struct token *list = tok_alloc();
- X char filename[BUFSIZ];
- X int lineno;
- X
- X /* Save context of '(' for diagnostics. */
- X
- X strcpy(filename, curr_path);
- X lineno = curr_line;
- X
- X list->tokno = TOK_LIST;
- X list->head = list->tail = t;
- X#ifdef DEBUG
- X strcpy(list->vstr->str, "LIST");
- X#endif
- X
- X for (;;) {
- X if ((t = tok_get(DO_WSPACE)) == 0) { /* skip blanks */
- X error_where(0, filename, lineno, "unmatched '('");
- X return (list); /* do not waste any data */
- X }
- X switch (t->tokno) {
- X case ')': /* end of list */
- X tok_free(t);
- X return (list);
- X case '{': /* struct/union type */
- X tok_list_struct(list->tail, t);
- X break;
- X case TOK_WSPACE: /* preserve trailing blanks */
- X tok_space_append(list->tail->tail, t); /* except after list */
- X break;
- X case '\n': /* preserve line count */
- X tok_flush(t);
- X break;
- X case ',': /* list separator */
- X tok_list_append(list, t);
- X break;
- X case '(': /* beginning of list */
- X tok_list_append(list->tail, tok_list(t));
- X break;
- X default: /* ordinary token */
- X tok_list_append(list->tail, t);
- X break;
- X }
- X }
- X}
- X
- X/* tok_list_struct - collect structured type info within list */
- X
- Xstatic void tok_list_struct(list, t)
- Xregister struct token *list;
- Xregister struct token *t;
- X{
- X tok_list_append(list, t);
- X
- X while (t = tok_class(DO_WSPACE)) {
- X switch (t->tokno) {
- X case '\n': /* preserve line count */
- X tok_flush(t);
- X break;
- X case TOK_WSPACE: /* preserve trailing blanks */
- X tok_space_append(list->tail, t); /* except after list */
- X break;
- X case '{': /* recurse */
- X tok_list_struct(list, t);
- X break;
- X case '}': /* done */
- X tok_list_append(list, t);
- X return;
- X default: /* other */
- X tok_list_append(list, t);
- X break;
- X }
- X }
- X}
- X
- X/* tok_list_append - append data to list */
- X
- Xstatic void tok_list_append(h, t)
- Xstruct token *h;
- Xstruct token *t;
- X{
- X if (h->head == 0) {
- X h->head = h->tail = t;
- X } else {
- X h->tail->next = t;
- X h->tail = t;
- X }
- X}
- END_OF_tok_class.c
- if test 4091 -ne `wc -c <tok_class.c`; then
- echo shar: \"tok_class.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f tok_io.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"tok_io.c\"
- else
- echo shar: Extracting \"tok_io.c\" \(9985 characters\)
- sed "s/^X//" >tok_io.c <<'END_OF_tok_io.c'
- X/*++
- X/* NAME
- X/* tok_io 3
- X/* SUMMARY
- X/* token I/O
- X/* PACKAGE
- X/* unproto
- X/* SYNOPSIS
- X/* #include "token.h"
- X/*
- X/* struct token *tok_get(skip_flag)
- X/* int skip_flag;
- X/*
- X/* void tok_unget(t)
- X/* struct token *t;
- X/*
- X/* void tok_flush(t)
- X/* struct token *t;
- X/*
- X/* void tok_show(t)
- X/* struct token *t;
- X/*
- X/* void put_str(s)
- X/* char *s;
- X/*
- X/* void put_ch(c)
- X/* int c;
- X/*
- X/* void show_line_control()
- X/*
- X/* char curr_path[];
- X/* int curr_line;
- X/* DESCRIPTION
- X/* These functions read from stdin and write to stdout. The
- X/* output functions maintain some memory so that two successive
- X/* words will always be separated by white space.
- X/*
- X/* The input routines eliminate backslash-newline from the input.
- X/*
- X/* tok_get() reads the next token from standard input. It returns
- X/* a null pointer when the end of input is reached. If the skip_flag
- X/* argument is nonzero, white space (except newline) will be skipped.
- X/*
- X/* tok_unget() implements a limited amount of token push back.
- X/*
- X/* tok_show() displays the contents of a (possibly composite) token
- X/* on the standard output.
- X/*
- X/* tok_flush() displays the contents of a (possibly composite) token
- X/* on the standard output and makes it available for re-use.
- X/*
- X/* put_str() writes a null-terminated string to standard output.
- X/*
- X/* put_ch() writes one character to standard output.
- X/*
- X/* show_line_control() displays the line number of the next line
- X/* to be written to standard output, in a format suitable for the C
- X/* compiler parser phase.
- X/*
- X/* The curr_path[] and curr_line variables contain the input file name and
- X/* line number of the most recently read token.
- X/* BUGS
- X/* The tokenizer is just good enough for the unproto filter.
- X/* As a benefit, it is quite fast.
- X/* AUTHOR(S)
- X/* Wietse Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* LAST MODIFICATION
- X/* 91/11/30 21:10:26
- X/* VERSION/RELEASE
- X/* 1.2
- X/*--*/
- X
- Xstatic char io_sccsid[] = "@(#) tok_io.c 1.2 91/11/30 21:10:26";
- X
- X/* C library */
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X
- Xextern char *strchr();
- Xextern char *malloc();
- Xextern char *realloc();
- Xextern char *strcpy();
- X
- X/* Application-specific stuff */
- X
- X#include "token.h"
- X#include "vstring.h"
- X#include "error.h"
- X
- X/* Stuff to keep track of original source file name and position */
- X
- Xchar curr_path[BUFSIZ]; /* current file name */
- Xint curr_line = 0; /* # of last read line */
- X
- X/* Forward declarations */
- X
- Xstatic void read_quoted();
- Xstatic void read_comment();
- X
- X/* Buffered i/o stuff */
- X
- Xstatic struct vstring *buf = 0; /* read-ahead buffer */
- Xstatic char *bp = ""; /* buffer position */
- X
- X#ifdef DEBUG
- X#define INITBUF 1 /* small initial buffer size */
- X#else
- X#define INITBUF BUFSIZ /* reasonable initial buffer size */
- X#endif
- X
- X#define input() (*bp ? *bp++ : next_line())
- X#define unput(c) (*--bp = (c))
- X
- X#define TOK_BUFSIZE 5 /* token push-back buffer size */
- X
- Xstatic struct token *tok_buf[TOK_BUFSIZE];
- Xstatic int tok_bufpos = 0;
- X
- X/* Type of last token sent to output, for pretty printing */
- X
- Xstatic int last_tok = 0;
- X
- X/* Directives that should be ignored. */
- X
- X#ifdef IGNORE_DIRECTIVES
- X
- Xstatic char *ignore_directives[] = {
- X IGNORE_DIRECTIVES,
- X 0,
- X};
- X
- X#endif
- X
- X/* Modified string and ctype stuff. */
- X
- X#define STREQUAL(x,y) (*(x) == *(y) && strcmp((x),(y)) == 0)
- X
- X#define ISALNUM(c) (isalnum(c) || (c) == '_')
- X#define ISALPHA(c) (isalpha(c) || (c) == '_')
- X#define ISSPACE(c) (isspace(c) && c != '\n')
- X#define ISDOT(c) (c == '.')
- X
- X/* Collect all characters that satisfy one condition */
- X
- X#define COLLECT(v,c,cond) { \
- X register struct vstring *vs = v; \
- X register char *cp = vs->str; \
- X *cp++ = c; \
- X for (;;) { \
- X if ((c = input()) == 0) { \
- X break; \
- X } else if (cond) { \
- X if (VS_ADDCH(vs, cp, c) == 0) \
- X error(1, "out of memory"); \
- X } else { \
- X unput(c); \
- X break; \
- X } \
- X } \
- X *cp = 0; \
- X }
- X
- X/* do_control - parse control line, uses tok_get() */
- X
- Xstatic int do_control()
- X{
- X struct token *t1;
- X struct token *t2;
- X int pass_thru = 1; /* 0 = ignore, 1 = output */
- X
- X (void) input(); /* skip the hash */
- X
- X if (t1 = tok_get(NO_WSPACE)) {
- X switch (t1->tokno) {
- X
- X /*
- X * In case of line number control, the remainder of the line has
- X * the format: linenumber "pathname".
- X */
- X case TOK_NUMBER:
- X if (t2 = tok_get(NO_WSPACE)) {
- X if (t2->tokno == '"') {
- X curr_line = atoi(t1->vstr->str) - 1;
- X strcpy(curr_path, t2->vstr->str);
- X }
- X tok_free(t2);
- X }
- X break;
- X
- X#ifdef IGNORE_DIRECTIVES
- X case TOK_WORD:
- X /* Optionally ignore other #directives, such as #pragma. */
- X {
- X char **cpp;
- X char *cp = t1->vstr->str;
- X
- X for (cpp = ignore_directives; *cpp; cpp++) {
- X if (STREQUAL(cp, *cpp)) {
- X pass_thru = 0;
- X break;
- X }
- X }
- X }
- X break;
- X#endif
- X }
- X tok_free(t1);
- X }
- X return (pass_thru);
- X}
- X
- X/* next_line - read one logical line, handle #control */
- X
- Xstatic int next_line()
- X{
- X register int c;
- X register char *cp;
- X
- X /* Allocate buffer upon first entry */
- X
- X if (buf == 0)
- X buf = vs_alloc(INITBUF);
- X
- X for (;;) {
- X cp = buf->str;
- X
- X /* Account for EOF and line continuations */
- X
- X while ((c = getchar()) != EOF) {
- X if (VS_ADDCH(buf, cp, c) == 0) /* store character */
- X error(1, "out of memory");
- X if (c == '\n') { /* real end of line */
- X curr_line++;
- X break;
- X } else if (c == '\\') {
- X if ((c = getchar()) == EOF) { /* XXX strip backslash-EOF */
- X break;
- X } else if (c == '\n') { /* strip backslash-newline */
- X curr_line++;
- X put_ch('\n'); /* preserve line count */
- X cp--; /* un-store backslash */
- X } else {
- X ungetc(c, stdin); /* keep backslash-other */
- X }
- X }
- X }
- X *cp = 0;
- X bp = buf->str;
- X
- X /* Account for EOF and #control */
- X
- X switch (bp[0]) {
- X case 0: /* EOF */
- X return (0);
- X case '#': /* control */
- X if (do_control())
- X fputs(buf->str, stdout); /* pass through */
- X else
- X putchar('\n'); /* filter out */
- X break;
- X default: /* non-control */
- X return (input());
- X }
- X }
- X}
- X
- X/* tok_unget - push back one token */
- X
- Xvoid tok_unget(t)
- Xregister struct token *t;
- X{
- X if (tok_bufpos >= TOK_BUFSIZE)
- X error(1, "too much pushback");
- X tok_buf[tok_bufpos++] = t;
- X}
- X
- X/* tok_get - get next token */
- X
- Xstruct token *tok_get(skip_flag)
- Xint skip_flag;
- X{
- X register struct token *t;
- X register int c;
- X int d;
- X
- X /* Use push-back token, if any. */
- X
- X if (tok_bufpos) {
- X t = tok_buf[--tok_bufpos];
- X return (t);
- X }
- X
- X /*
- X * Get one from the pool and fill it in. The loop is here in case we
- X * should skip white-space tokens, which happens in a minority of all
- X * cases.
- X */
- X
- X t = tok_alloc();
- X
- X for (;;) {
- X if ((c = input()) == 0) {
- X tok_free(t);
- X return (0);
- X } else if (!isascii(c)) {
- X t->vstr->str[0] = c;
- X t->vstr->str[1] = 0;
- X t->tokno = TOK_OTHER;
- X return (t);
- X } else if (c == '"' || c == '\'') {
- X read_quoted(t, c);
- X t->tokno = c;
- X return (t);
- X } else if (ISALPHA(c)) {
- X COLLECT(t->vstr, c, ISALNUM(c));
- X t->tokno = TOK_WORD;
- X return (t);
- X } else if (isdigit(c)) {
- X COLLECT(t->vstr, c, isdigit(c));
- X t->tokno = TOK_NUMBER;
- X return (t);
- X } else if (ISSPACE(c)) {
- X COLLECT(t->vstr, c, ISSPACE(c));
- X if (skip_flag)
- X continue;
- X t->tokno = TOK_WSPACE;
- X return (t);
- X } else if (ISDOT(c)) {
- X COLLECT(t->vstr, c, ISDOT(c));
- X t->tokno = TOK_OTHER;
- X return (t);
- X } else {
- X t->vstr->str[0] = c;
- X if (c == '/') {
- X if ((d = input()) == '*') {
- X t->vstr->str[1] = d; /* comment */
- X read_comment(t->vstr);
- X if (skip_flag)
- X continue;
- X t->tokno = TOK_WSPACE;
- X return (t);
- X } else {
- X unput(d);
- X }
- X }
- X t->vstr->str[1] = 0;
- X t->tokno = c;
- X return (t);
- X }
- X }
- X}
- X
- X/* read_qouted - read string or character literal */
- X
- Xstatic void read_quoted(t, ch)
- Xregister struct token *t;
- Xint ch;
- X{
- X register char *cp = t->vstr->str;
- X register int c;
- X
- X *cp++ = ch;
- X
- X while (c = input()) {
- X if (c == '\n') { /* newline in string */
- X unput(c);
- X break;
- X }
- X if (VS_ADDCH(t->vstr, cp, c) == 0) /* store character */
- X error(1, "out of memory");
- X if (c == ch) /* end of string */
- X break;
- X if (c == '\\') /* eat next character */
- X if ((c = input()) != 0 && VS_ADDCH(t->vstr, cp, c) == 0)
- X error(1, "out of memory");
- X }
- X *cp = 0;
- X return;
- X}
- X
- X/* read_comment - stuff a whole comment into one huge token */
- X
- Xstatic void read_comment(vs)
- Xregister struct vstring *vs;
- X{
- X register char *cp = vs->str + 2; /* skip slash star */
- X register int c;
- X register int d;
- X
- X while (c = input()) {
- X if (VS_ADDCH(vs, cp, c) == 0)
- X error(1, "out of memory");
- X if (c == '*') {
- X if ((d = input()) == '/') {
- X if (VS_ADDCH(vs, cp, d) == 0)
- X error(1, "out of memory");
- X break;
- X } else {
- X unput(d);
- X }
- X }
- X }
- X *cp = 0;
- X}
- X
- X/* put_str - output a string */
- X
- Xvoid put_str(s)
- Xchar *s;
- X{
- X fputs(s, stdout);
- X last_tok = s[0]; /* XXX */
- X#ifdef DEBUG
- X fflush(stdout);
- X#endif
- X}
- X
- X/* put_ch - put character */
- X
- Xvoid put_ch(c)
- Xint c;
- X{
- X last_tok = putchar(c);
- X#ifdef DEBUG
- X fflush(stdout);
- X#endif
- X}
- X
- X/* tok_show - output (possibly composite) token */
- X
- Xvoid tok_show(t)
- Xstruct token *t;
- X{
- X register struct token *p;
- X register struct token *s;
- X
- X switch (t->tokno) {
- X case TOK_LIST:
- X for (s = t->head; s; s = s->next) {
- X put_ch(s->tokno); /* opening paren or ',' */
- X for (p = s->head; p; p = p->next)
- X tok_show(p);
- X }
- X put_ch(')'); /* closing paren */
- X break;
- X case TOK_WORD:
- X if (ISALPHA(last_tok))
- X putchar(' ');
- X /* FALLTRHOUGH */
- X default:
- X fputs(t->vstr->str, stdout); /* token contents */
- X last_tok = t->vstr->str[0];
- X#ifdef DEBUG
- X fflush(stdout);
- X#endif
- X if (t->head) /* trailing blanks */
- X for (p = t->head; p; p = p->next)
- X tok_show(p);
- X }
- X}
- END_OF_tok_io.c
- if test 9985 -ne `wc -c <tok_io.c`; then
- echo shar: \"tok_io.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f tok_pool.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"tok_pool.c\"
- else
- echo shar: Extracting \"tok_pool.c\" \(2184 characters\)
- sed "s/^X//" >tok_pool.c <<'END_OF_tok_pool.c'
- X/*++
- X/* NAME
- X/* tok_pool 3
- X/* SUMMARY
- X/* maintain pool of unused token structures
- X/* PACKAGE
- X/* unproto
- X/* SYNOPSIS
- X/* #include "token.h"
- X/*
- X/* struct token *tok_alloc()
- X/*
- X/* void tok_free(t)
- X/* struct token *t;
- X/* DESCRIPTION
- X/* tok_alloc() and tok_free() maintain a pool of unused token
- X/* structures.
- X/*
- X/* tok_alloc() takes the first free token structure from the pool
- X/* or allocates a new one if the pool is empty.
- X/*
- X/* tok_free() adds a (possibly composite) token structure to the pool.
- X/* BUGS
- X/* The pool never shrinks.
- X/* AUTHOR(S)
- X/* Wietse Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* LAST MODIFICATION
- X/* 91/09/01 23:08:36
- X/* VERSION/RELEASE
- X/* 1.1
- X/*--*/
- X
- Xstatic char pool_sccsid[] = "@(#) tok_pool.c 1.1 91/09/01 23:08:36";
- X
- X/* C library */
- X
- Xextern char *malloc();
- X
- X/* Application-specific stuff */
- X
- X#include "token.h"
- X#include "vstring.h"
- X
- Xextern void error();
- X
- X#define TOKLEN 5 /* initial string buffer length */
- X
- Xstruct token *tok_pool = 0; /* free token pool */
- X
- X/* tok_alloc - allocate token structure from pool or heap */
- X
- Xstruct token *tok_alloc()
- X{
- X register struct token *t;
- X
- X if (tok_pool) { /* re-use an old one */
- X t = tok_pool;
- X tok_pool = t->next;
- X } else { /* create a new one */
- X if ((t = (struct token *) malloc(sizeof(struct token))) == 0
- X || (t->vstr = vs_alloc(TOKLEN)) == 0)
- X error(1, "out of memory");
- X }
- X t->next = t->head = t->tail = 0;
- X#ifdef DEBUG
- X strcpy(t->vstr->str, "BUSY");
- X#endif
- X return (t);
- X}
- X
- X/* tok_free - return (possibly composite) token to pool of free tokens */
- X
- Xvoid tok_free(t)
- Xregister struct token *t;
- X{
- X#ifdef DEBUG
- X /* Check if we are freeing free token */
- X
- X register struct token *p;
- X
- X for (p = tok_pool; p; p = p->next)
- X if (p == t)
- X error(1, "freeing free token");
- X#endif
- X
- X /* Free neighbours and subordinates first */
- X
- X if (t->next)
- X tok_free(t->next);
- X if (t->head)
- X tok_free(t->head);
- X
- X /* Free self */
- X
- X t->next = tok_pool;
- X t->head = t->tail = 0;
- X tok_pool = t;
- X#ifdef DEBUG
- X strcpy(t->vstr->str, "FREE");
- X#endif
- X}
- END_OF_tok_pool.c
- if test 2184 -ne `wc -c <tok_pool.c`; then
- echo shar: \"tok_pool.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f token.h -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"token.h\"
- else
- echo shar: Extracting \"token.h\" \(1523 characters\)
- sed "s/^X//" >token.h <<'END_OF_token.h'
- X/* @(#) token.h 1.3 91/11/30 21:10:37 */
- X
- Xtypedef struct token {
- X int tokno; /* token value, see below */
- X int len; /* string or list length */
- X struct vstring *vstr; /* token contents */
- X struct token *next;
- X struct token *head;
- X struct token *tail;
- X};
- X
- X/* Special token values */
- X
- X#define TOK_LIST 256 /* () delimited list */
- X#define TOK_WORD 257 /* keyword or identifier */
- X#define TOK_NUMBER 258 /* number */
- X#define TOK_WSPACE 259 /* white space except newline */
- X#define TOK_OTHER 260 /* other multi-char token */
- X#define TOK_CONTROL 261 /* flow control keyword */
- X#define TOK_COMPOSITE 262 /* struct or union */
- X
- X/* Input/output functions and macros */
- X
- Xextern struct token *tok_get(); /* read next single token */
- Xextern void tok_show(); /* display (composite) token */
- Xextern struct token *tok_class(); /* classify tokens */
- Xextern void put_ch(); /* write character */
- Xextern void put_str(); /* write string */
- Xextern void tok_unget(); /* stuff token back into input */
- X
- X#define tok_flush(t) (tok_show(t), tok_free(t))
- X
- X/* tok_get() and tok_class() options */
- X
- X#define DO_WSPACE 0 /* retain space, tab */
- X#define NO_WSPACE 1 /* skip space, tab */
- X
- X/* Memory management */
- X
- Xstruct token *tok_alloc(); /* allocate token storage */
- Xextern void tok_free(); /* re-cycle storage */
- X
- X/* Context */
- X
- Xextern char curr_path[]; /* current path name */
- Xextern int curr_line; /* current line number */
- X#define show_line_control() printf("# %d %s\n", curr_line, curr_path);
- END_OF_token.h
- if test 1523 -ne `wc -c <token.h`; then
- echo shar: \"token.h\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f unproto.1 -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"unproto.1\"
- else
- echo shar: Extracting \"unproto.1\" \(2067 characters\)
- sed "s/^X//" >unproto.1 <<'END_OF_unproto.1'
- X.TH UNPROTO 1
- X.ad
- X.fi
- X.SH NAME
- Xunproto
- X\-
- XANSI C to old C converter
- X.SH PACKAGE
- X.na
- X.nf
- Xunproto
- X.SH SYNOPSIS
- X.na
- X.nf
- X/lib/cpp ... | unproto
- X
- X/somewhere/cpp ...
- X.SH DESCRIPTION
- X.ad
- X.fi
- XThis document describes a filter that sits between the
- XC preprocessor (usually \fI/lib/cpp\fP) and the next C compiler
- Xpass. It rewrites ANSI-C style function headers, function type
- Xdeclarations, function pointer types, and function pointer casts
- Xto old style. Other ANSI-isms are passed on without modification
- X(token pasting, pragmas, etcetera).
- X
- XFor maximal flexibility, the "cpp | unproto" pipeline can be
- Xpackaged as an executable shell script named "/somewhere/cpp".
- XThis script should then be specified to the C compiler as a
- Xnon-default preprocessor.
- X
- XThe overhead of shell script interpretation can be avoided by
- Xhaving the unprototyper itself open the pipe to the preprocessor.
- XIn that case, the source should be compiled with the PIPE_THROUGH_CPP
- Xmacro defined (usually as "/lib/cpp"), and the resulting binary
- Xshould be installed as "/somewhere/cpp".
- X.SH SEE ALSO
- X.na
- X.nf
- X.ad
- X.fi
- Xcc(1), how to specify a non-default C preprocessor.
- X
- XSome versions of the lint command are implemented as a shell
- Xscript. It should require only minor modification for integration
- Xwith the unprotoizer. Other versions of the lint command accept the same
- Xcommand syntax as the C compiler for the specification of a non-default
- Xpreprocessor. Some research may be needed.
- X.SH DIAGNOSTICS
- X.ad
- X.fi
- XThe progam will complain if it unexpectedly
- Xreaches the end of input.
- X.SH BUGS
- X.ad
- X.fi
- XShould be run on preprocessed source only, i.e. after macro expansion.
- X
- XDeclarations of (whatever) are misunderstood and will result in
- Xsyntax errors.
- X
- XDoes not generate explicit type casts for function argument
- Xexpressions.
- X.SH AUTHOR(S)
- X.na
- X.nf
- XWietse Venema (wietse@wzv.win.tue.nl)
- XEindhoven University of Technology
- XDepartment of Mathematics and Computer Science
- XDen Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X.SH LAST MODIFICATION
- X.na
- X.nf
- X91/09/22 21:21:35
- X.SH VERSION/RELEASE
- X.na
- X.nf
- X1.2
- END_OF_unproto.1
- if test 2067 -ne `wc -c <unproto.1`; then
- echo shar: \"unproto.1\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f varargs.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"varargs.c\"
- else
- echo shar: Extracting \"varargs.c\" \(606 characters\)
- sed "s/^X//" >varargs.c <<'END_OF_varargs.c'
- X /*
- X * @(#) varargs.c 1.1 91/09/01 23:08:45
- X *
- X * This program can be used to verify that the stdarg.h file is set up
- X * correctly for your system. If it works, it should print one line with the
- X * text "stdarg.h works".
- X */
- X
- X#include <stdio.h>
- X#include "stdarg.h"
- X
- Xmain(int argc, char *argv[])
- X{
- X varargs_test("%s %s\n", "stdarg.h", "works");
- X}
- X
- Xvarargs_test(char *fmt, ...)
- X{
- X va_list ap;
- X
- X va_start(ap, fmt);
- X while (*fmt) {
- X if (strncmp("%s", fmt, 2) == 0) {
- X fputs(va_arg(ap, char *), stdout);
- X fmt += 2;
- X } else {
- X putchar(*fmt);
- X fmt++;
- X }
- X }
- X va_end(ap);
- X}
- END_OF_varargs.c
- if test 606 -ne `wc -c <varargs.c`; then
- echo shar: \"varargs.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f vstring.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"vstring.c\"
- else
- echo shar: Extracting \"vstring.c\" \(2328 characters\)
- sed "s/^X//" >vstring.c <<'END_OF_vstring.c'
- X/*++
- X/* NAME
- X/* vs_alloc(), VS_ADDCH()
- X/* SUMMARY
- X/* auto-resizing string library
- X/* PACKAGE
- X/* vstring
- X/* SYNOPSIS
- X/* #include "vstring.h"
- X/*
- X/* struct vstring *vs_alloc(len)
- X/* int len;
- X/*
- X/* int VS_ADDCH(vs, wp, ch)
- X/* struct vstring *vs;
- X/* char *wp;
- X/* int ch;
- X/* DESCRIPTION
- X/* These functions and macros implement a small library for
- X/* arbitrary-length strings that grow automatically when
- X/* they fill up. The allocation strategy is such that there
- X/* will always be place for the terminating null character.
- X/*
- X/* vs_alloc() allocates storage for a variable-length string.
- X/*
- X/* VS_ADDCH() adds a character to a variable-length string
- X/* and automagically extends the string if fills up.
- X/* \fIvs\fP is a pointer to a vstring structure; \fIwp\fP
- X/* the current write position in the corresponding character
- X/* array; \fIch\fP the character value to be written.
- X/* Note that VS_ADDCH() is a macro that evaluates some
- X/* arguments more than once.
- X/* DIAGNOSTICS
- X/* VS_ADDCH() returns zero if it was unable to dynamically
- X/* resize a string.
- X/*
- X/* vs_alloc() returns a null pointer in case of problems.
- X/* BUGS
- X/* Auto-resizing may change the address of the string data in
- X/* a vstring structure. Beware of dangling pointers.
- X/* AUTHOR(S)
- X/* Wietse Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* LAST MODIFICATION
- X/* 91/09/22 21:21:38
- X/* VERSION/RELEASE
- X/* 1.2
- X/*--*/
- X
- Xstatic char vstring_sccsid[] = "@(#) vstring.c 1.2 91/09/22 21:21:38";
- X
- X/* C library */
- X
- Xextern char *malloc();
- Xextern char *realloc();
- X
- X/* Application-specific stuff */
- X
- X#include "vstring.h"
- X
- X/* vs_alloc - initial string allocation */
- X
- Xstruct vstring *vs_alloc(len)
- Xint len;
- X{
- X register struct vstring *vp;
- X
- X if (len < 1
- X || (vp = (struct vstring *) malloc(sizeof(struct vstring))) == 0
- X || (vp->str = malloc(len)) == 0)
- X return (0);
- X vp->last = vp->str + len - 1;
- X return (vp);
- X}
- X
- X/* vs_realloc - extend string, update write pointer */
- X
- Xchar *vs_realloc(vp, cp)
- Xregister struct vstring *vp;
- Xchar *cp;
- X{
- X int where = cp - vp->str;
- X int len = vp->last - vp->str + 1;
- X
- X if ((vp->str = realloc(vp->str, len *= 2)) == 0)
- X return (0);
- X vp->last = vp->str + len - 1;
- X return (vp->str + where);
- X}
- END_OF_vstring.c
- if test 2328 -ne `wc -c <vstring.c`; then
- echo shar: \"vstring.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f vstring.h -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"vstring.h\"
- else
- echo shar: Extracting \"vstring.h\" \(410 characters\)
- sed "s/^X//" >vstring.h <<'END_OF_vstring.h'
- X/* @(#) vstring.h 1.1 91/09/01 23:08:42 */
- X
- Xstruct vstring {
- X char *str; /* string value */
- X char *last; /* last position */
- X};
- X
- Xextern struct vstring *vs_alloc(); /* initial allocation */
- Xextern char *vs_realloc(); /* string extension */
- X
- X/* macro to add one character to auto-resized string */
- X
- X#define VS_ADDCH(vs,wp,c) \
- X ((wp < (vs)->last || (wp = vs_realloc(vs,wp))) ? (*wp++ = c) : 0)
- END_OF_vstring.h
- if test 410 -ne `wc -c <vstring.h`; then
- echo shar: \"vstring.h\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- echo shar: End of archive 1 \(of 2\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked both archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-